本文同步分享於個人部落格:Liwen Chiou | Digital Architect & Full-Stack Engineer
孩子,在踏上今日的領地前,先坐下來喝杯酒吧。
修煉的路很長,別急著奔跑,先聽聽這份卷軸裡的古老叮嚀。我在每一站的盡頭都為你鋪設了 「
實戰演武場 CodePen」。那不只是程式碼的拼湊,而是你在這場暴風雨中,試圖用邏輯點燃的一顆星火。
成功突圍後,別忘了帶著你的戰利品回到 「QuestBoard 佈告欄」。在那裡,你會發現自己從不孤單,公會的夥伴們都正舉杯等待你的歸來。記住...
「 導師看重的從來不是你的劍法有多華麗,而是當你被邏輯擊潰、滿身泥濘後,依然選擇握緊理性的劍柄,再次向真相發起衝鋒的勇氣。 」
「還記得昨天那個『藍色鎧甲變紅色』的靈異事件嗎?」我推開公會圖書館中一台發著微光的舊機器——那是祕傳的影印裝置。
在 JavaScript 的世界裡,物件與陣列的靈魂是連在一起的。只要你稍不留神分享了鑰匙,兩者的命運就會被強制綁架。今天,我要教你公會最強的保命符—— 「展開運算子 (...)」。這招能幫你瞬間斷開與原版資料的「靈魂連結」,還能讓你像玩樂高一樣,自由地合併、擴充與更新你的戰備物資!
展開運算子 ... 的動作極其簡單:它就是把裝在「陣列」或「物件」裡的舊物資全部「倒出來」,放在空中供你重新運用。
const oldScrolls = ["火球術", "治癒術"];
// ✅ 影印術:變出一個新木箱 [],再把舊捲軸 ... 倒進去
const newScrolls = [...oldScrolls, "傳送術"];
console.log(newScrolls); // ["火球術", "治癒術", "傳送術"]
console.log(oldScrolls); // ["火球術", "治癒術"] (原版毫髮無傷,連結已斷開!)
影印術最強的地方在於,你可以在合併的瞬間,對資料進行「進化」。
const baseSkill = { category: "魔法", mp: 10 };
const fireball = { name: "火球術", mp: 50 };
// ✅ 兩組合併:後面的內容會蓋掉前面的内容 (Overwriting)
// 就像是在新箱子裡先放舊零件,再把改良零件丟進去,重複的會被替換。
const superFireball = {
...baseSkill,
...fireball,
level: "Max",
};
console.log(superFireball);
// { category: "魔法", name: "火球術", mp: 50, level: "Max" }
🏹 導師的辨析圖:影印與連結
| 修煉招式 | 標籤賦值 (=) |
展開影印 (...) |
|---|---|---|
| 核心結果 | 共享同一把鑰匙 | 打造全新實體 |
| 修改副作用 | A 改,B 跟著變 | 各走各路,互不干擾 |
| 記憶體狀態 | 指向同一個地址 | 產生獨立新地址 |
導師的圖解心法: 想像這是一個 「影印現場」。展開運算子就像是一台快速影印機,它把大箱子(物件)的殼印了一份,但裡面的貴重保險箱(嵌套物件)依然只有一張 「同樣的提貨單」。而深拷貝則是直接派人去另一個城市,重新打造了一個完全一模一樣、且內外都獨立的新保箱。

const teamA = ["戰士", "法師"];
const teamB = ["牧師", "弓箭手"];
// 雖然能用 concat,但在多組數據合併時會變得很混亂
const fullTeam = teamA.concat(teamB);
const teamA = ["戰士", "法師"];
const teamB = ["牧師", "弓箭手"];
// 像把兩個麻袋直接打開倒進大麻袋一樣簡單
const fullTeam = [...teamA, ...teamB];
導師講評: 學長的寫法就像是在戰場上同時召喚兩支軍隊,你一眼就能看出最終的「大名單」長什麼樣子。這就是程式碼的「描述力」。
孩子,別以為 ... 是無敵的。它雖然會影印大箱子,但如果箱子裡還裝著 「另一個小箱子」,影印機印出來的依然是 同一把小箱子的鑰匙。
const hero = { name: "辛梅爾", bag: { coin: 10 } };
const clone = { ...hero };
clone.bag.coin = 999;
console.log(hero.bag.coin); // 999 (救命!裡層物件還是連著的!)
當你處理「多層嵌套」的物資時,請記得:展開運算子只管第一層。
當你的寶箱裡疊了好幾層箱子(嵌套物件)時,我們需要施展更徹底的「次元斷開術」。
招式 A:次元切割術 (JSON.parse/stringify)
這是公會裡最古老也最常用的招式。我們先將整個物件轉化為 「無靈魂的字串 (JSON)」,再將字串重新生成為一個 「全新的物件」。
const hero1 = { name: "勇者", bag: { coin: 10 } };
const hero2 = JSON.parse(JSON.stringify(hero1)); // ✂️ 徹底斷開!
hero2.bag.coin = 999;
console.log(hero1.bag.coin); // 10 (成功守衛!第一、二層都不再連動)
導師叮嚀: 此招雖然強大,但它會遺忘物件裡的「魔法招式 (Function)」與「特殊印記 (Symbol)」。
招式 B:高階影印機 (structuredClone())
這是近年來公會引進的最高階武器。它能無損複製循環引用與特殊數據類型,但它極度排斥 「魔法函式 (Function)」。
⚔️ 職人級警告: 如果你的物件裡藏著咒語(函式),發動
structuredClone()會導致 「次元崩潰 (DataCloneError)」。這就是為什麼資深前輩會說:「深拷貝資料時,請確保裡面只裝著純粹的物資,不要裝著會動的靈魂。」
除了「倒出來」,... 還能當作 「萬能麻袋」,把它放在函式的接收處,它能捕捉所有剩餘的資料。
function captureLoot(firstGold, ...others) {
console.log(`金幣:${firstGold}`);
console.log(`其餘雜物:`, others); // others 自動變成陣列
}
孩子,導師當年維護「世界地圖物件」時,因為不懂
...的重要性,直接const newMap = currentMap;
就去修改地圖上的魔王城位置。結果那一秒,全伺服器的冒險者看到的地圖都亂了套,原本的新手村旁邊突然出現了魔王。那天我收到了公會歷史上最多的投訴信。
記住:「如果你打算修改某份前人傳下來的物件,請先『影印一份新的』再動手。這是身為資深勇者最基本的溫柔。」
天色微亮,營火雖已燃盡,但你眼中卻閃爍著領悟的光芒。在前往演武場挑戰關卡前,我已經幫你把靈魂碎片精煉成了這份「戰術錦囊」。拿好它,今日的任務不再是負擔,而是你證明自我的舞台。去吧,公會的英雄榜在等著你的戰報。
...,用於拆開容器。[...old] 或 {...old} 產生新副本,斷開傳址連結。... 收集剩餘資料。📜 本日實戰任務:影印術與麻袋收集器 (CodePen)
🛡️ 任務達成證明:QuestBoard 公會報到處
... 斷開影子分身的那一刻,你有沒有感受到數據終於「受你控制」的自由感?gear 裡面裝著一個「自動修復函式 (Function)」,為什麼使用 JSON.parse(JSON.stringify()) 影印後,這招魔法會消失不見?